package assess

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"gitcode.com/G-YT/iHealth25/server/global"
	"gitcode.com/G-YT/iHealth25/server/model/assess"
	assessRes "gitcode.com/G-YT/iHealth25/server/model/assess/response"
	"gitcode.com/G-YT/iHealth25/server/model/common/response"
	"gitcode.com/G-YT/iHealth25/server/utils"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"strconv"
	"strings"
)

type AssessApi struct {
}

// GetPhysiqueQuestion 获取体质问卷
// @Tags Assess
// @Summary 获取体质辨别页面
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query user.User true "获取体质辨别页面"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /api/assess/getPhysiqueDiscernPage [get]
func (a *AssessApi) GetPhysiqueQuestion(c *gin.Context) {
	var ItemInfo []assess.Item
	qConf, _ := AssessService.QuestionConf()
	for key, value := range qConf {
		item := assess.Item{
			Key: base64.StdEncoding.EncodeToString([]byte(key)),
			Msg: value,
		}
		ItemInfo = append(ItemInfo, item)
	}
	response.Result(200, ItemInfo, "获取成功!", c)
	return
}

// SubmitPhysiqueQuestion 提交体质问卷
// @Tags Assess
// @Summary 用id查询用户
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query user.User true "提交体质问卷"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"提交成功"}"
// @Router /api/assess/submitPhysiqueQuestion [post]
func (a *AssessApi) SubmitPhysiqueQuestion(c *gin.Context) {
	var question assess.PhysiqueQuestionLog
	e := c.ShouldBindJSON(&question)
	if e != nil {
		response.FailWithMessage(e.Error(), c)
		return
	}
	id := utils.GetUserID(c)
	var results map[string]int
	if err := json.Unmarshal([]byte(question.Results), &results); err != nil {
		response.FailWithMessage("无效的问卷答案结果集", c)
		return
	}
	// 计算分值及体质
	UserPhysique, _ := AssessService.GetPhysique(results, question.Birthday)
	LowTension := question.LowTension
	if question.LowTension == ",,,," {
		LowTension = "0,0,0,0,0"
	} else {
		LowTension = question.LowTension
	}
	HighTension := question.HighTension
	if question.HighTension == ",,,," {
		HighTension = "0,0,0,0,0"
	} else {
		HighTension = question.HighTension
	}
	// 拿到体质ID
	Pid, _ := PhysiqueService.GetPhysiqueId(UserPhysique.Physique)
	questionData := &assess.PhysiqueQuestionLog{
		BloodType:                question.BloodType,
		BloodSugar:               question.BloodSugar,
		HRV:                      question.HRV,
		BloodConcentration:       question.BloodConcentration,
		HRres:                    question.HRres,
		BloodConcentrationLowNum: question.BloodConcentrationLowNum,
		LowTension:               LowTension,
		HighTension:              HighTension,
		Birthday:                 question.Birthday,
		Results:                  question.Results,
		ScoreData:                UserPhysique.Score,
		Physique:                 UserPhysique.Physique,
		PhysiqueId:               Pid.ID,
		Uid:                      id,
		Remark:                   "",
		Ph:                       question.Ph,
		Mah:                      question.Mah,
		Phi:                      question.Phi,
		Sh:                       question.Sh,
		Hs:                       question.Hs,
		Pacemaker:                question.Pacemaker,
		Other:                    question.Other,
	}
	if logID, err := AssessService.CreatePhysiqueQuestionLog(questionData); err != nil {
		global.GVA_LOG.Error("提交失败!", zap.Error(err))
		response.FailWithMessage("提交失败", c)
	} else {
		response.Result(200, logID, "提交成功", c)
	}
}

// GetQuestionResultList 获取问卷结果列表
// @Tags Assess
// @Summary 获取问卷结果列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query user.User true "获取问卷结果列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /api/assess/getQuestionResultList [get]
func (a *AssessApi) GetQuestionResultList(c *gin.Context) {
	id := utils.GetUserID(c)
	UserPhysiqueList, _ := AssessService.GetPhysiqueQuestionList(map[string]interface{}{"uid": id}, "id,created_at,physique_id,habitus,score_data")
	results := make([]assessRes.QuestionResultResponse, 0)
	for _, value := range UserPhysiqueList {
		dataMap := make(map[string]int)
		if err := json.Unmarshal([]byte(value.ScoreData), &dataMap); err != nil {
			fmt.Printf("JSON解析失败: %v\n", err)
			continue
		}
		var data assessRes.Data
		for k, v := range dataMap {
			decoded, _ := base64.StdEncoding.DecodeString(k)
			data.Title = append(data.Title, string(decoded))
			data.Score = append(data.Score, v)
		}
		data.Remark = value.Remark
		results = append(results, assessRes.QuestionResultResponse{
			ID:        value.ID,
			Habitus:   value.Physique + "质",
			CreatedAt: value.CreatedAt,
			Data:      data,
		})
	}
	response.Result(200, results, "获取成功", c)
}

// GetOneQuestionResultByID 根据ID获取问卷结果
// @Tags Assess
// @Summary 根据ID获取问卷结果
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query user.User true "根据ID获取问卷结果"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"提交成功"}"
// @Router /api/assess/getOneQuestionResultByID [get]
func (a *AssessApi) GetOneQuestionResultByID(c *gin.Context) {
	id := c.Query("id")
	UserPhysique, _ := AssessService.GetPhysiqueQuestionLog(map[string]interface{}{"id": id}, "id,created_at,score_data,habitus,remark")
	data := make(map[string]int)
	err := json.Unmarshal([]byte(UserPhysique.ScoreData), &data)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	var result assessRes.Data
	for k, v := range data {
		decoded, _ := base64.StdEncoding.DecodeString(k)
		result.Title = append(result.Title, string(decoded))
		result.Score = append(result.Score, v)
	}
	if UserPhysique.ID == 0 {
		response.FailWithMessage("您还没有进行过体质评测!", c)
		return
	} else {
		response.Result(200,
			assessRes.QuestionResultResponse{
				ID:        UserPhysique.ID,
				Habitus:   UserPhysique.Physique + "质",
				CreatedAt: UserPhysique.CreatedAt,
				Data: assessRes.Data{
					Title:  result.Title,
					Score:  result.Score,
					Remark: UserPhysique.Remark,
				},
			}, "获取成功", c)
	}
}

// GetQuestionResult 获取问卷结果
// @Tags Assess
// @Summary 获取问卷结果
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query user.User true "获取问卷结果"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /api/assess/getQuestionResult [get]
func (a *AssessApi) GetQuestionResult(c *gin.Context) {
	id := utils.GetUserID(c)
	UserPhysique, _ := AssessService.GetPhysiqueQuestionLog(map[string]interface{}{"uid": id}, "id,created_at,score_data,habitus,remark")
	data := make(map[string]int)
	err := json.Unmarshal([]byte(UserPhysique.ScoreData), &data)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	var result assessRes.Data
	for k, v := range data {
		decoded, _ := base64.StdEncoding.DecodeString(k)
		result.Title = append(result.Title, string(decoded))
		result.Score = append(result.Score, v)
	}
	if UserPhysique.ID == 0 {
		response.FailWithMessage("您还没有进行过体质评测!", c)
		return
	} else {
		response.Result(200,
			assessRes.QuestionResultResponse{
				ID:        UserPhysique.ID,
				Habitus:   UserPhysique.Physique + "质",
				CreatedAt: UserPhysique.CreatedAt,
				Data: assessRes.Data{
					Title:  result.Title,
					Score:  result.Score,
					Remark: UserPhysique.Remark,
				},
			}, "获取成功", c)
	}
}

// GetQuestionResultByID 根据用户ID获取问卷结果
// @Tags Assess
// @Summary 根据用户ID获取问卷结果
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query user.User true "根据用户ID获取问卷结果"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"提交成功"}"
// @Router /api/assess/getQuestionResultByID [get]
func (a *AssessApi) GetQuestionResultByID(c *gin.Context) {
	id := c.Query("id")
	UserPhysique, _ := AssessService.GetPhysiqueQuestionLog(map[string]interface{}{"uid": id}, "id,created_at,score_data,habitus,remark")
	data := make(map[string]int)
	err := json.Unmarshal([]byte(UserPhysique.ScoreData), &data)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	var result assessRes.Data
	for k, v := range data {
		decoded, _ := base64.StdEncoding.DecodeString(k)
		result.Title = append(result.Title, string(decoded))
		result.Score = append(result.Score, v)
	}
	if UserPhysique.ID == 0 {
		response.FailWithMessage("您还没有进行过体质评测!", c)
		return
	} else {
		response.Result(200,
			assessRes.QuestionResultResponse{
				ID:        UserPhysique.ID,
				Habitus:   UserPhysique.Physique + "质",
				CreatedAt: UserPhysique.CreatedAt,
				Data: assessRes.Data{
					Title:  result.Title,
					Score:  result.Score,
					Remark: UserPhysique.Remark,
				},
			}, "获取成功", c)
	}
}

// GetLatelyReport 查询最近报告
// @Tags Assess
// @Summary 查询最近报告
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query user.User true "查询最近报告"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"提交成功"}"
// @Router /api/assess/getLatelyReport [get]
func (a *AssessApi) GetLatelyReport(c *gin.Context) {
	idStr := c.Query("id")
	id, _ := strconv.ParseUint(idStr, 10, 64)
	userInfo, err := UserService.FindUserByID(uint(id))
	if err != nil {
		response.FailWithDetailed("", "用户不存在", c)
		return
	}
	pql, err := AssessService.GetPhysiqueQuestionLog(map[string]interface{}{"uid": id}, "created_at,blood_type,blood_sugar,HRres,blood_concentration,low_tension,high_tension,HRV,ph,mah,phi,sh,hs,pacemaker,other")
	if err != nil {
		response.FailWithDetailed("", "该用户暂无报告", c)
		return
	}
	Age := UserService.CalculateAge(userInfo.Birthday)
	var Sex string
	if userInfo.Sex == 1 {
		Sex = "男"
	} else {
		Sex = "女"
	}
	result := &assessRes.LatelyReport{
		Id:                 userInfo.ID,
		Name:               userInfo.Name,
		Sex:                Sex,
		Age:                Age,
		ICE:                userInfo.UrgentCard.ContactPhone,
		BloodType:          pql.BloodType,
		BloodSugar:         pql.BloodSugar,
		HRres:              pql.HRres,
		BloodConcentration: pql.BloodConcentration,
		LowTension:         pql.LowTension,
		HighTension:        pql.HighTension,
		HRV:                pql.HRV,
		Ph:                 pql.Ph,
		Mah:                pql.Mah,
		Phi:                pql.Phi,
		Sh:                 pql.Sh,
		Hs:                 pql.Hs,
		Pacemaker:          pql.Pacemaker,
		Other:              pql.Other,
		CreatedAt:          pql.CreatedAt,
	}
	response.Result(200, result, "获取成功", c)
}

// GetEfficacyList 获取功效列表
// @Tags Assess
// @Summary 获取功效列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query user.User true "获取功效列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /api/assess/getEfficacyList [get]
func (a *AssessApi) GetEfficacyList(c *gin.Context) {
	var ae assessRes.EfficacyList
	uid := utils.GetUserID(c)
	efficacyInfo, _ := EfficacyService.GetEfficacyTagByUid(uid)
	efficacyList, _ := EfficacyService.GetEfficacyList()
	if efficacyInfo.ID != 0 {
		ae.IsExist = true
	} else {
		ae.IsExist = false
	}
	// 填充ae结构体
	for _, v := range efficacyList {
		list := assessRes.List{
			Name:    v.Name,
			IsExist: false,
			ID:      strconv.Itoa(int(v.ID)),
		}
		// 检查功效ID是否在e_ids字段中
		if efficacyInfo.Eids != "" {
			ids := strings.Split(efficacyInfo.Eids, ",")
			for _, id := range ids {
				if id == strconv.Itoa(int(v.ID)) {
					list.IsExist = true
					break
				}
			}
		}
		ae.List = append(ae.List, list)
	}
	response.Result(200, ae, "获取成功", c)
}

// SaveUserEfficacyTag 保存用户功效标签
// @Tags Assess
// @Summary 提交用户功效标签
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query user.User true "保存用户功效标签"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"保存成功"}"
// @Router /api/assess/submitUserEfficacyTag [post]
func (a *AssessApi) SaveUserEfficacyTag(c *gin.Context) {
	var au assess.UserEfficacyTag
	err := c.ShouldBindJSON(&au)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	verify := utils.Rules{
		"Eids": {utils.NotEmpty()},
	}
	if err := utils.Verify(au, verify); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	uid := utils.GetUserID(c)
	efficacyInfo, _ := EfficacyService.GetEfficacyTagByUid(uid)
	// 判断是否存在用户功效标签
	au.ID = uid
	if efficacyInfo.ID != 0 {
		if err := EfficacyService.UpdateUserEfficacyTag(au.ID, au.Eids); err != nil {
			global.GVA_LOG.Error("保存失败!", zap.Error(err))
			response.FailWithMessage("保存失败", c)
		}
	} else {
		if err := EfficacyService.CreateUserEfficacyTag(&au); err != nil {
			global.GVA_LOG.Error("保存失败!", zap.Error(err))
			response.FailWithMessage("保存失败", c)
		}
	}
	response.Result(200, "", "保存成功", c)
}
